import java.io.FileNotFoundException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import org.olap4j.CellSet;
import org.olap4j.CellSetAxis;
import org.olap4j.OlapConnection;
import org.olap4j.OlapWrapper;
import org.olap4j.Position;
import org.olap4j.PreparedOlapStatement;
import org.olap4j.metadata.Member;

public class CubeDao {
	public static final String URL = "jdbc:xmla:Server=http://10.20.14.40:9999/olap/msmdpump.dll;Catalog=\"烟草数据中心\"";
	public static final String USER = "\"datacenter\\\\yangchen\"";
	public static final String PASSWORD = "\"Neu_sdyc\"";
	public static String DRIVER_NAME = "org.olap4j.driver.xmla.XmlaOlap4jDriver";

	public static String query(String mdx) throws ClassNotFoundException,
			SQLException, FileNotFoundException {
		mdx = mdx.replace("<br>", " ");
		System.out.println(mdx);
		Class.forName(DRIVER_NAME);
		OlapConnection con = (OlapConnection) DriverManager.getConnection(URL,
				USER, PASSWORD);
		OlapWrapper wrapper = (OlapWrapper) con;
		OlapConnection olapConnection = (OlapConnection) wrapper
				.unwrap(OlapConnection.class);
		PreparedOlapStatement postmt = olapConnection.prepareOlapStatement(mdx);
		CellSet cellSet = postmt.executeQuery();

		String[][] colss = parseColsToArray(cellSet);
		String[][] rowss = parseRowsToArray(cellSet);
		String[][] datass = parseDatassToArray(cellSet);
		System.out.println("colss");
		printArr(colss);
		System.out.println("rowss");
		printArr(rowss);
		System.out.println("datass");
		printArr(datass);
		// printArr(reverseArr(colss));
		System.out.println("json");
		String json = packageToJson(colss, rowss, datass);
		// System.out.println(json);
		return json;
	}

	private static String packageToJson(String[][] colss, String[][] rowss,
			String[][] datass) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("{columns : ");
		String columnsJson = packageToColumnsJson(colss, rowss);
		buffer.append(columnsJson).append(",fieldsNames : ");
		String fieldsNamesJson = packageToFieldsNamesJson(colss, rowss);
		buffer.append(fieldsNamesJson).append(",data : ");
		String dataJson = packageToDataJson(fieldsNamesJson, datass, rowss);
		buffer.append(dataJson).append("}");
		return buffer.toString();
	}

	private static String packageToDataJson(String fieldsNamesJson,
			String[][] datass, String[][] rowss) {
		StringBuffer buffer = new StringBuffer("[");

		String substring = fieldsNamesJson.substring(1,
				fieldsNamesJson.length() - 1);

		String[] dataIndex = substring.split(",");
		for (int i = 0; i < datass.length; i++) {
			buffer.append(0 == i ? "" : ",");
			buffer.append("{");
			for (int j = 0; j < dataIndex.length; j++) {
				buffer.append(0 == j ? "" : ",");
				int j2 = 0;
				if (null == rowss) {

				} else {
					j2 = rowss[i].length;
				}

				if (j < j2) {
					buffer.append(dataIndex[j]).append(":'")
							.append(rowss[i][j]).append("'");
				} else {
					try {
						buffer.append(dataIndex[j]).append(":'")
								.append(datass[i][j - j2]).append("'");
					} catch (Exception e) {
						System.out.println(i);
						System.out.println(j);
						e.printStackTrace();
					}
				}

			}
			buffer.append("}");
		}
		buffer.append("]");
		return buffer.toString();
	}

	private static String packageToFieldsNamesJson(String[][] colss,
			String[][] rowss) {
		StringBuffer buffer = new StringBuffer("[");
		if (null == rowss) {

		} else {
			int lockedColLength = rowss[0].length;
			for (int i = 0; i < lockedColLength; i++) {
				buffer.append(0 == i ? "" : ",");
				buffer.append("'").append("0-").append(i).append("'");
			}
			buffer.append(0 != lockedColLength ? "," : "");
		}
		LinkedHashMap<Object, Object> linkedHashMap = new LinkedHashMap<Object, Object>();
		for (int i = 0; i < colss.length; i++) {
			arrToMap4Cols(linkedHashMap, colss[i], 0);
		}
		buffer.append(mapToString4FieldsNames(new StringBuffer(""),
				linkedHashMap, 1));
		buffer.append("]");
		return buffer.toString();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static String mapToString4FieldsNames(StringBuffer stringBuffer,
			LinkedHashMap<Object, Object> linkedHashMap, int path) {
		if (linkedHashMap.isEmpty()) {
			return stringBuffer.toString();
		}
		int i = 1;
		for (Iterator iterator = linkedHashMap.entrySet().iterator(); iterator
				.hasNext(); i++) {
			Entry entry = (Entry) iterator.next();
			LinkedHashMap value = (LinkedHashMap) entry.getValue();
			if (value.isEmpty()) {
				stringBuffer
						.append(0 == stringBuffer.length()
								|| !"'".equals(String.valueOf(stringBuffer
										.charAt(stringBuffer.length() - 1))) ? ""
								: ",");
				stringBuffer.append("'" + path + "-" + i + "'");
			} else {
				stringBuffer.append(0 == stringBuffer.length() ? "" : ",");
				mapToString4FieldsNames(stringBuffer, value, i);
			}
		}
		return stringBuffer.toString();
	}

	private static String packageToColumnsJson(String[][] colss,
			String[][] rowss) {
		StringBuffer buffer = new StringBuffer("[");
		if (null == rowss) {

		} else {
			int lockedColLength = rowss[0].length;
			for (int i = 0; i < lockedColLength; i++) {
				buffer.append(0 == i ? "" : ",");
				buffer.append("{");
				buffer.append("dataIndex : '").append("0-").append(i)
						.append("',");
				buffer.append("locked : true");
				buffer.append("}");
			}
			buffer.append(0 == lockedColLength ? "" : ",");
		}
		LinkedHashMap<Object, Object> linkedHashMap = new LinkedHashMap<Object, Object>();
		for (int i = 0; i < colss.length; i++) {
			arrToMap4Cols(linkedHashMap, colss[i], 0);
		}
		buffer.append(mapToString4cols(new StringBuffer(""), linkedHashMap, 1));
		buffer.append("]");
		return buffer.toString();
	}

	@SuppressWarnings("rawtypes")
	private static String mapToString4cols(StringBuffer stringBuffer,
			LinkedHashMap linkedHashMap, int path) {
		if (linkedHashMap.isEmpty()) {
			return stringBuffer.toString();
		}
		int i = 1;
		for (Iterator iterator = linkedHashMap.entrySet().iterator(); iterator
				.hasNext(); i++) {
			Entry entry = (Entry) iterator.next();
			String uniqueName = format((String) entry.getKey());
			LinkedHashMap value = (LinkedHashMap) entry.getValue();
			if (value.isEmpty()) {
				stringBuffer
						.append(0 == stringBuffer.length()
								|| !"}".equals(String.valueOf(stringBuffer
										.charAt(stringBuffer.length() - 1))) ? ""
								: ",");
				stringBuffer.append("{header : '" + uniqueName
						+ "',dataIndex : '" + path + "-" + i + "'}");
				mapToString4cols(stringBuffer, value, i);
			} else {
				stringBuffer.append(0 == stringBuffer.length() ? "" : ",");
				stringBuffer.append("{text : '" + uniqueName + "',columns : [");
				mapToString4cols(stringBuffer, value, i);
				stringBuffer.append("]}");
			}
		}
		return stringBuffer.toString();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static void arrToMap4Cols(LinkedHashMap linkedHashMap,
			String[] cols, int i) {
		if (i >= cols.length) {
			return;
		}
		String uniqueName = cols[i];
		LinkedHashMap<String, LinkedHashMap> childLinkedHashMap = null;
		if (!linkedHashMap.containsKey(uniqueName)) {
			childLinkedHashMap = new LinkedHashMap();
			linkedHashMap.put(uniqueName, childLinkedHashMap);
		} else {
			childLinkedHashMap = (LinkedHashMap) linkedHashMap.get(uniqueName);
		}
		arrToMap4Cols(childLinkedHashMap, cols, ++i);
	}

	private static String[][] parseColsToArray(CellSet cellSet) {
		CellSetAxis cellSetAxis = cellSet.getAxes().get(0);
		String[][] colss = new String[cellSetAxis.getPositionCount()][];
		for (int i = 0, max = cellSetAxis.getPositionCount(); i < max; i++) {
			Position position = cellSetAxis.getPositions().get(i);
			List<Member> members = position.getMembers();
			String[] cols = new String[members.size()];
			for (int j = 0, max2 = members.size(); j < max2; j++) {
				Member member = (Member) members.get(j);
				// String uniqueName = member.getUniqueName();
				String caption = member.getCaption();
				cols[j] = caption;
			}
			colss[i] = cols;
		}
		return colss;
	}

	private static String[][] parseRowsToArray(CellSet cellSet) {
		List<CellSetAxis> axes = cellSet.getAxes();
		if (axes.size() < 2) {
			return null;
		} else {
			CellSetAxis cellSetAxis = axes.get(1);
			String[][] rowss = new String[cellSetAxis.getPositionCount()][];
			for (int i = 0, max1 = cellSetAxis.getPositionCount(); i < max1; i++) {
				Position position = cellSetAxis.getPositions().get(i);
				List<Member> members = position.getMembers();
				String[] rows = new String[members.size()];
				for (int j = 0, max2 = members.size(); j < max2; j++) {
					Member member = (Member) members.get(j);
					// String uniqueName = member.getUniqueName();
					String caption = member.getCaption();
					rows[j] = caption;
				}
				rowss[i] = rows;
			}
			return rowss;
		}
	}

	private static String[][] parseDatassToArray(CellSet cellSet) {
		List<CellSetAxis> axes = cellSet.getAxes();
		if (axes.size() < 2) {
			CellSetAxis axisCol = cellSet.getAxes().get(0);
			// CellSetAxis axisRow = cellSet.getAxes().get(1);
			List<Position> positionsCol = axisCol.getPositions();
			// List<Position> positionsRow = axisRow.getPositions();
			String[][] datass = new String[1][];
			String[] datas = new String[positionsCol.size()];
			for (int i = 0, max1 = axisCol.getPositionCount(); i < max1; i++) {
				String value = String.valueOf(cellSet.getCell(
						positionsCol.get(i)).getValue());
				datas[i] = value;
			}
			datass[0] = datas;
			return datass;
		} else {
			CellSetAxis axisCol = axes.get(0);
			CellSetAxis axisRow = axes.get(1);
			List<Position> positionsCol = axisCol.getPositions();
			List<Position> positionsRow = axisRow.getPositions();
			String[][] datass = new String[axisRow.getPositionCount()][];
			for (int i = 0, max1 = axisRow.getPositionCount(); i < max1; i++) {
				String[] datas = new String[positionsCol.size()];
				for (int j = 0, max2 = positionsCol.size(); j < max2; j++) {
					String value = String.valueOf(cellSet.getCell(
							positionsCol.get(j), positionsRow.get(i))
							.getFormattedValue());
					datas[j] = "null".equals(value) ? "0" : value;
				}
				datass[i] = datas;
			}
			return datass;
		}
	}

	private static String[][] reverseArr(String[][] arrSrc) {
		String[][] arrTar = new String[arrSrc[0].length][arrSrc.length];
		for (int i = 0; i < arrSrc.length; i++) {
			for (int j = 0; j < arrSrc[i].length; j++) {
				arrTar[j][i] = arrSrc[i][j];
			}
		}
		return arrTar;
	}

	private static void printArr(String[][] arr) {
		StringBuffer buffer = new StringBuffer("[");
		if (null == arr) {
			System.out.println("[[]]");
		} else {
			for (int i = 0; i < arr.length; i++) {
				buffer.append(0 == i ? "" : ",").append("[");
				for (int j = 0; j < arr[i].length; j++) {
					buffer.append(0 == j ? "" : ",").append(arr[i][j]);
				}
				buffer.append("]");
			}
			buffer.append("]");
			System.out.println(buffer.toString());
		}
	}

	private static String format(String src) {
		return src.replaceAll("\\[", "&#91;").replaceAll("\\]", "&#93;")
				.replaceAll("\\.", "&#46;");
	}

	public static void main(String[] args) throws ClassNotFoundException,
			SQLException, FileNotFoundException {
		String mdx = "select NON EMPTY {[日期维].[年-月-日].[年]*[组织维].[公司-部门].[公司] } on columns , NON EMPTY {[Measures].[购进数量【万支】]*[商品维].[品牌].[品牌] } on rows from [卷烟经营] ";
		String mdx2 = "select NON EMPTY {[组织维].[公司-部门].[公司] } on columns , NON EMPTY {[日期维].[年-月-日].[年] } on rows from [卷烟经营] ";
		CubeDao.query(mdx);
	}
}
